package com.duckclouddrive.controller;

import com.duckclouddrive.annotation.GlobalInterceptor;
import com.duckclouddrive.annotation.VerifyParam;
import com.duckclouddrive.component.RedisComponent;
import com.duckclouddrive.entity.dto.SessionWebUserDto;
import com.duckclouddrive.entity.dto.SysSettingsDto;
import com.duckclouddrive.entity.enums.FileCategoryEnums;
import com.duckclouddrive.entity.enums.FileDelFlagEnums;
import com.duckclouddrive.entity.enums.UserStatusEnum;
import com.duckclouddrive.entity.po.FileShare;
import com.duckclouddrive.entity.po.UserInfo;
import com.duckclouddrive.entity.query.FileInfoQuery;
import com.duckclouddrive.entity.query.UserInfoQuery;
import com.duckclouddrive.entity.vo.FileInfoVO;
import com.duckclouddrive.entity.vo.PaginationResultVO;
import com.duckclouddrive.entity.vo.ResponseVO;
import com.duckclouddrive.entity.vo.UserInfoVO;
import com.duckclouddrive.mappers.FileInfoMapper;
import com.duckclouddrive.mappers.UserInfoMapper;
import com.duckclouddrive.service.FileInfoService;
import com.duckclouddrive.service.FileShareService;
import com.duckclouddrive.service.UserInfoService;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

@RestController("adminController")
@RequestMapping("/admin")
public class AdminController extends  CommonFileController{
   @Resource
   private FileShareService fileShareService;

   @Resource
   private RedisComponent redisComponent;
   @Resource
   private FileInfoService fileInfoService;
   @Resource
   private FileInfoMapper fileInfoMapper;
   @Resource
   private UserInfoMapper userInfoMapper;

   @Resource
   private UserInfoService userInfoService;
   @RequestMapping("/getSysSettings")
   @GlobalInterceptor(checkAdmin = true, checkParams = true)
   public ResponseVO getSysSetting() {
       return getSuccessResponseVO(redisComponent.getSysSettingsDto());
   }

    /**
     * 保存系统设置信息
     *
     * @param registerEmailTitle 注册邮件标题，必需
     * @param registerEmailContent 注册邮件内容，必需
     * @param userInitUseSpace 用户初始使用空间，必需
     * @return 返回响应对象，包含处理结果
     *
     * 此方法用于保存系统设置，包括注册邮件的标题、内容和用户初始使用空间
     * 它需要管理员权限，并对传入参数进行验证
     */
    @RequestMapping("/saveSysSettings")
    @GlobalInterceptor(checkAdmin = true, checkParams = true)
    public ResponseVO saveSysSetting(@VerifyParam(required = true) String registerEmailTitle, @VerifyParam(required = true) String registerEmailContent,@VerifyParam(required = true)  String userInitUseSpace) {
        // 创建系统设置对象
        SysSettingsDto sysSettingsDto = new SysSettingsDto();
        // 设置注册邮件内容
        sysSettingsDto.setRegisterEmailContent(registerEmailContent);
        // 设置注册邮件标题
        sysSettingsDto.setRegisterEmailTitle(registerEmailTitle);
        // 设置用户初始使用空间，需要将字符串转换为整数
        sysSettingsDto.setUserInitUseSpace(Integer.parseInt(userInitUseSpace));
        // 将系统设置信息保存到Redis中
        redisComponent.saveSysSettingsDto(sysSettingsDto);
        // 返回成功响应
        return getSuccessResponseVO(null);
    }

    /**
     * 加载用户列表接口
     * 该方法用于获取经过分页处理的用户信息列表，且仅限管理员操作
     *
     * @param userInfoQuery 用户信息查询条件，包括分页信息和查询过滤条件
     * @return 返回一个包含用户信息列表的ResponseVO对象
     */
    @RequestMapping("/loadUserList")
    @GlobalInterceptor(checkAdmin = true, checkParams = true)
    public ResponseVO loadUserList(@VerifyParam(required = true)UserInfoQuery userInfoQuery) {
        // 设置默认排序方式，按加入时间降序排列
        userInfoQuery.setOrderBy("join_time desc");
        // 调用服务层方法，根据查询条件获取分页后的用户信息
        PaginationResultVO resultVO = userInfoService.findListByPage(userInfoQuery);
        // 将查询结果转换为分页VO，并封装到成功响应对象中返回
        return getSuccessResponseVO(convert2PaginationVO(resultVO, UserInfoVO.class));
    }


    @RequestMapping("/updateUserStatus")
    @GlobalInterceptor(checkAdmin = true, checkParams = true)
    public ResponseVO updateUserStatus(@VerifyParam(required = true)String userId,
                                       @VerifyParam(required = true) Integer status) {
        userInfoService.updateUserStatus(userId, status);
        return getSuccessResponseVO(null);
   }

    /**
     * 更新用户空间
     *
     * 本方法通过修改用户的存储空间来响应用户的请求
     * 它依赖于后端的userInfoService来执行实际的空间变更操作
     *
     * @param userId 用户唯一标识符，用于确定要修改的用户
     * @param changeSpace 用户空间的变更量，正值表示增加空间，负值表示减少空间
     * @return ResponseVO 返回一个表示操作结果的响应对象，包含操作状态和数据
     */
    @RequestMapping("/updateUserSpace")
    @GlobalInterceptor(checkParams = true, checkAdmin = true)
    public ResponseVO updateUserSpace(@VerifyParam(required = true) String userId, @VerifyParam(required = true) Integer changeSpace) {
        userInfoService.changeUserSpace(userId, changeSpace);
        return getSuccessResponseVO(null);
    }

    @RequestMapping("/loadFileList")
    @GlobalInterceptor(checkAdmin = true, checkParams = true)
    public ResponseVO loadFileList(FileInfoQuery query) {
        //设置查询结果的排序方式，按照最后更新时间降序排列
        query.setOrderBy("last_update_time desc");

        query.setQueryNickName(true);

        // 调用服务方法，根据查询条件获取分页的文件列表结果
        PaginationResultVO result = fileInfoService.findListByPage(query);
        // 将结果转换为统一的响应格式，并返回
        return getSuccessResponseVO(result);
    }

    /**
     * 获取文件夹信息
     *
     * 该方法用于获取指定路径的文件夹信息它被映射到"/getFolderInfo" URL，并且配置了全局拦截器
     * 以允许管理员在不检查登录状态的情况下访问此方法，但需要进行参数校验
     *
     * @param path 文件夹路径，是获取信息所必需的参数
     * @return 返回一个包含文件夹信息的ResponseVO对象
     */
    @RequestMapping("/getFolderInfo")
    @GlobalInterceptor(checkLogin = false,checkAdmin = true, checkParams = true)
    public ResponseVO getFolderInfo(@VerifyParam(required = true) String path) {
        return super.getFolderInfo(path, null);
    }


    /**
     * 根据用户ID和文件ID获取文件,文件预览
     * 该方法用于处理通过用户ID和文件ID获取特定文件的请求
     * 它使用了请求映射和全局拦截器来控制访问权限和验证参数
     *
     * @param response 用于向客户端发送响应的对象
     * @param userId   请求路径中的用户ID，用于识别用户
     * @param fileId   请求路径中的文件ID，用于定位文件
     */
    @RequestMapping("/getFile/{userId}/{fileId}")
    @GlobalInterceptor(checkParams = true, checkAdmin = true)
    public void getFile(HttpServletResponse response,
                        @PathVariable("userId") @VerifyParam(required = true) String userId,
                        @PathVariable("fileId") @VerifyParam(required = true) String fileId) {
        super.getFile(response, fileId, userId);
    }

    /**
     * 根据用户ID和文件ID获取视频信息
     * 该方法用于处理通过用户ID和文件ID获取视频信息的请求
     * 主要功能包括：
     * 1. 验证请求参数的有效性
     * 2. 检查当前操作者是否为管理员
     * 3. 调用getFile方法获取指定用户的指定文件信息
     *
     * @param response 用于向客户端返回数据的响应对象
     * @param userId 用户ID，用于指定需要获取视频信息的用户
     * @param fileId 文件ID，用于指定需要获取信息的视频文件
     */
    @RequestMapping("/ts/getVideoInfo/{userId}/{fileId}")
    @GlobalInterceptor(checkParams = true, checkAdmin = true)
    public void getImage(HttpServletResponse response,
                         @PathVariable("userId")String userId,
                         @PathVariable("fileId")String fileId){
        super.getFile(response, fileId, userId);
    }
    @RequestMapping("/createDownloadUrl/{userId}/{fileId}")
    @GlobalInterceptor(checkParams = true)
    public ResponseVO createDownloadUrl(@PathVariable("userId") @VerifyParam(required = true) String userId,
                                        @PathVariable("fileId") @VerifyParam(required = true) String fileId){
        return super.createDownloadUrl(fileId, userId);
    }

    /**
     * 下载
     *
     * @param request
     * @param response
     * @throws Exception
     */
    @RequestMapping("/download/{code}")
    @GlobalInterceptor(checkLogin = false, checkParams = true)
    public void download(HttpServletRequest request, HttpServletResponse response,
                         @PathVariable("code") @VerifyParam(required = true) String code) throws Exception {
        super.download(request, response, code);
    }

    @RequestMapping("/delFile")
    @GlobalInterceptor(checkParams = true, checkAdmin = true)
    public ResponseVO delFile(@VerifyParam(required = true) String fileIdAndUserIds) {
        String[] fileIdAndUserIdArray = fileIdAndUserIds.split(",");
        for (String fileIdAndUserId : fileIdAndUserIdArray) {
            String[] itemArray = fileIdAndUserId.split("_");
            fileInfoService.delFileBatch(itemArray[0], itemArray[1], true);
        }
        return getSuccessResponseVO(null);
    }
}
